﻿// ------------------------------------------------------------------
// DO NOT REMOVE THIS LINES IN ANY TIMES WILL BE.
// Original author: agehack
// Project name: -
// ------------------------------------------------------------------

// Modification for WPF

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Windows;

namespace Agehack
{
    public static class InstanceControlTool
    {
        [DllImport("user32.dll")]
        private static extern int ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        private static extern int IsIconic(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern int SetForegroundWindow(IntPtr hWnd);


        public static IntPtr GetCurrentInstanceWindowHandle()
        {
            IntPtr hWnd = IntPtr.Zero;
            Process process = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(process.ProcessName);
            foreach (Process _process in processes)
            {
                // Get the first instance that is not this instance, has the
                // same process name and was started from the same file name
                // and location. Also check that the process has a valid
                // window handle in this session to filter out other user's
                // processes.
                if (_process.Id != process.Id &&
                _process.MainModule.FileName == process.MainModule.FileName &&
                _process.MainWindowHandle != IntPtr.Zero)
                {
                    hWnd = _process.MainWindowHandle;
                    break;
                }
            }
            return hWnd;
        }
        public static void SwitchToCurrentInstance()
        {
            IntPtr hWnd = GetCurrentInstanceWindowHandle();
            if (hWnd != IntPtr.Zero)
            {
                // Restore window if minimised. Do not restore if already in
                // normal or maximised window state, since we don't want to
                // change the current state of the window.
                if (IsIconic(hWnd) != 0)
                {
                    ShowWindow(hWnd, SW_RESTORE);
                }

                // Set foreground window.
                SetForegroundWindow(hWnd);
            }
        }
        public static void SwitchToOtherInstance()
        {
            //Find the first process which has same name & filename,
            //and are not this process,
            //Get main window handle of this process
            //and set it as foreground window:
            Process[] prcs = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            Process ths = Process.GetCurrentProcess();
            foreach (Process p in prcs)
            {
                if ((p != null && p != ths) && (p.StartInfo.FileName == Process.GetCurrentProcess().StartInfo.FileName && p.ProcessName == Process.GetCurrentProcess().ProcessName))
                {
                    int r = SetForegroundWindow(p.MainWindowHandle);
                }
            }
        }
        public static bool CheckAnyAnotherInstancesRunning(bool focus)
        {
            if (IsAlreadyRunning())
            {
                if (focus)
                {
                    //set focus on previously running instance
                    SwitchToCurrentInstance();
                }
                return true;
            }
            else return false;
        }
        public static bool IsAlreadyRunning()
        {
            string strLoc = Assembly.GetExecutingAssembly().Location;
            FileSystemInfo fileInfo = new FileInfo(strLoc);
            string sExeName = fileInfo.Name;
            bool bCreatedNew;

            mutex = new Mutex(true, "Global\\" + sExeName, out bCreatedNew);
            if (bCreatedNew)
                mutex.ReleaseMutex();

            return !bCreatedNew;
        }

        static Mutex mutex;
        const int SW_RESTORE = 9;

        public static bool SecureInstances(bool message, bool switchToOriginalInstance)
        {
            if (InstanceControlTool.IsAlreadyRunning())
            {
                if (message) MessageBox.Show("You cannot run a new instance of this application.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                if (switchToOriginalInstance) InstanceControlTool.SwitchToOtherInstance();
                return false;
            }
            else
                return true;
        }
    }
}